home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Revolution - Das Atari CD Magazin 1997
/
Revolution - Das Atari CD Magazin 1.iso
/
software
/
anwendng
/
qed_397
/
sourcen
/
file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-07
|
11KB
|
555 lines
/*
* file.c
*
* Da mir die ursprünlichen Lese/Schreib-Routinen viel zu undurchschaubar waren
* und ich z.B. kein Mac-Zeilenende nachrüsten konnte, habe ich eigene, deutlich
* einfachere Funktionen definiert.
* Die Methode mit dem 'if else if' beim Einlesen ist sicherlich nicht die
* schnellste, aber sie funktioniert und ist sehr übersichtlich :-)
* Auf dem TT gibt es keine bermerkbaren Geschwindigkeitsverluste!
*/
#include <errno.h>
#include "global.h"
#include "comm.h"
#include "mintlib.h"
#include "olga.h"
#include "rsc.h"
#include "scroll.h"
#include "text.h"
#include "file.h"
/* Puffer-Längen zum Lesen */
#define READBUFFSIZE 4*1024L
/*
* Bei Speichermangel ein Puffer, der eine Zeile plus
* Zeilenende aufnehmen kann (Lesen und Schreiben).
*/
#define STATICBUFFSIZE MAX_LINE_LEN + 3
LOCAL UBYTE static_buffer[STATICBUFFSIZE];
GLOBAL WORD load(TEXTP t_ptr, BOOLEAN quiet)
{
WORD antw;
antw = load_datei(t_ptr->filename, &t_ptr->text, TRUE, &t_ptr->ending);
t_ptr->cursor_line = t_ptr->text.head.nachf;
t_ptr->readonly = file_readonly(t_ptr->filename);
if (antw==0)
{
t_ptr->file_date_time = file_time(t_ptr->filename,NULL,NULL);
}
else
t_ptr->file_date_time = -1L;
if (antw!=0 && !quiet)
{
FILENAME datei;
PATH path;
file_splitt(t_ptr->filename, path, datei);
if (antw==-33 && path_exist(path)) /* file not found und Pfad existiert */
snote(1, NOTEXIST, datei);
else
snote(1, READERR, datei);
}
return(antw);
}
GLOBAL WORD load_datei(UBYTE *name, RINGP t, BOOLEAN verbose, LineEnding *end)
{
WORD fd, antw;
Busy_mouse();
fd = (short) Fopen(name, 0);
if (fd > 0)
{
LONG file_size;
/* größe der Datei ermitteln */
file_size = Fseek(0, fd, 2);
Fseek(0, fd, 0);
if (file_size >= 0L)
{
/* nicht schön, aber wirksam */
if ((LONG)Malloc(-1L) > file_size)
{
UBYTE *buffer, zeile[MAX_LINE_LEN + 3]; /* +2 für Zeilenende! */
LINEP start, next;
LONG buf_size, l, p, bytes;
WORD n;
BOOLEAN new_line, cr = FALSE;
/* Progress-Bar */
verbose = verbose && ((file_size >> 10) >= transfer_size);
if (verbose)
{
UBYTE str[40];
FILENAME file;
strcpy(str, STRING(LOADSTR));
file_name(name, file, FALSE);
strcat(str, file);
start_aktion(str, FALSE, file_size);
bytes = 0L;
}
/* Puffer anfordern */
buf_size = min(READBUFFSIZE, file_size);
buffer = (UBYTE *)Malloc(buf_size + 1);
if (buffer == NULL)
{
buffer = static_buffer;
buf_size = STATICBUFFSIZE;
}
/* Liste vorbereiten */
start = t->tail.vorg;
/* Einlesen */
l = Fread(fd, buf_size, buffer);
buffer[l] = EOS;
strcpy(zeile, "");
n = 0;
new_line = FALSE;
while (l > 0)
{
p = 0;
while (p < l)
{
if (buffer[p] == 0x0D) /* CR -> Mac */
{
new_line = TRUE;
p++;
cr = TRUE;
*end = apple;
}
else if (buffer[p] == 0x0A) /* LF */
{
p++;
if (cr) /* CRLF -> TOS*/
{
cr = FALSE;
*end = tos;
}
else
{
new_line = TRUE; /* -> Unix */
*end = unix;
}
}
else if (n >= MAX_LINE_LEN) /* Überlänge */
new_line = TRUE;
else
{
zeile[n] = buffer[p];
n++;
p++;
}
if (new_line)
{
zeile[n] = EOS;
start = start->nachf = new_col_w(zeile, n);
n = 0;
new_line = FALSE;
}
} /* while */
if (verbose)
{
bytes += buf_size;
do_aktion(bytes);
}
l = Fread(fd, buf_size, buffer);
/* EOF */
if (l == 0)
{
/* letzte Zeile ohne Zeilenende! */
if (n > 0)
{
zeile[n] = EOS;
start = start->nachf = new_col_w(zeile, n);
}
/* letzte Zeile hatte ZE -> ein Dummyzeile anhängen */
else if (n == 0)
start = start->nachf = new_col_b("", 0);
}
} /* while */
if (buffer != static_buffer)
Mfree(buffer);
/* Ring schließen */
t->tail.vorg = start;
start->nachf = &t->tail;
/* Anzahl der Zeilen ermitteln */
start = t->head.nachf;
next = start->nachf;
for (l = 0; !IS_TAIL(start); l++)
{
next->vorg = start;
start = next;
NEXT(next);
}
if (l > 1L)
{
col_delete(t->head.nachf);
l--;
}
t->lines = l;
if (verbose)
end_aktion();
antw = 0;
}
else
{
note(1, NOMEMORY);
antw = -39;
}
Fclose(fd);
}
else
antw = -1;
}
else
antw = fd;
Last_mouse();
return(antw);
}
/*
* Ermittelt die anzahl der Bytes und Zeilen der übergebenen Datei.
* Wird bei der Projektverwaltung (Info) benutzt.
*/
GLOBAL WORD infoload(UBYTE *name, LONG *bytes, LONG *lines)
{
RING t;
WORD antw;
LineEnding ending;
init_textring(&t);
if (load_datei(name, &t, FALSE, &ending) == 0)
{
*bytes = textring_bytes(&t, ending);
*lines = t.lines;
antw = 0;
}
else
antw = 1;
kill_textring(&t);
return antw;
}
/****************************************************************************/
LONG VOID backup_name(UBYTE *name, UBYTE *ext)
{
PATH new;
strcpy(new, name);
strcat(new, ".");
strcat(new, ext);
if (longName(new) >= strlen(new))
strcpy(name, new);
else
make_ext(name, ext);
}
LOCAL VOID restore_back_up(TEXTP t_ptr)
{
if (t_ptr->loc_opt->backup)
{
PATH old;
if (file_exist(t_ptr->filename))
Fdelete(t_ptr->filename);
strcpy(old, t_ptr->filename);
backup_name(old, t_ptr->loc_opt->backup_ext);
Frename(0, old, t_ptr->filename);
}
}
LOCAL VOID back_up(TEXTP t_ptr)
{
PATH new;
if (t_ptr->loc_opt->backup)
{
Busy_mouse();
strcpy(new, t_ptr->filename);
backup_name(new, t_ptr->loc_opt->backup_ext);
if (file_exist(new)) /* Alte DUP-Datei löschen */
Fdelete(new);
Frename(0, t_ptr->filename, new);
Last_mouse();
}
}
GLOBAL WORD save_datei(UBYTE *name, RINGP t, BOOLEAN verbose, LineEnding ending)
{
WORD fd, antw;
Busy_mouse();
fd = (short) Fcreate(name, 0);
if (fd > 0)
{
UBYTE *buffer, end_str[3], zeile[MAX_LINE_LEN + 3], *ptr;
WORD z_len;
LONG buf_size, text_size, b, ret, rest, count;
LINEP lauf;
/* Puffer anfordern */
text_size = textring_bytes(t, ending);
buffer = (UBYTE *)Malloc(text_size + 1);
if (buffer == NULL)
{
buffer = static_buffer;
buf_size = STATICBUFFSIZE;
}
else
buf_size = text_size;
buffer[0] = EOS;
/* Progress-Bar */
verbose = verbose && ((text_size >> 10) >= transfer_size);
if (verbose)
{
UBYTE str[40];
FILENAME file;
strcpy(str, STRING(SAVESTR));
file_name(name, file, FALSE);
strcat(str,file);
start_aktion(str, FALSE, t->lines);
count = 0L;
}
/* String mit Zeilenende erzeugen */
switch (ending)
{
case tos :
strcpy(end_str, "\r\n");
break;
case unix :
strcpy(end_str, "\n");
break;
case apple :
strcpy(end_str, "\r");
break;
default:
strcpy(end_str, "");
break;
}
/* Text im Puffer verketten und wegschreiben */
lauf = FIRST(t);
if (lauf != NULL)
{
b = 0L;
ret = 1;
ptr = buffer;
rest = buf_size;
while ((!IS_TAIL(lauf)) && (ret > 0))
{
/* Zeile aus Text und Zeilenende zusammen setzen */
strcpy(zeile, TEXT(lauf));
/*
* Das Zeilenende wird nur dann angehängt, wenn lauf nicht letzte
* Zeile ist. Gab es beim Laden der Datei in der letzten Zeile
* ein ZE, gibt es die Dummyzeile. Gab es das ZE nicht, wird auch
* kein ZE angehängt!
*/
if (!IS_LAST(lauf))
strcat(zeile, end_str);
z_len = (short)strlen(zeile);
/* Passt die Zeile noch in den Puffer? */
if (z_len < rest)
{
/* komplett in den Puffer */
ptr = COPYB(ptr, zeile, z_len);
b += z_len;
rest -= z_len;
}
else
{
/* nur soviel kopieren, wie noch passt */
ptr = COPYB(ptr, zeile, (short)rest);
/* wegschreiben */
ret = Fwrite(fd, buf_size, buffer);
if (ret != buf_size)
ret = -ENOSPC;
/* und den Rest in den Puffer */
b = z_len - rest;
ptr = COPYB(buffer, zeile+rest, (short)b);
rest = buf_size - b;
}
if (verbose)
{
count++;
do_aktion(count);
}
NEXT(lauf);
}
/* Befindet sich noch etwas im Puffer und ist kein Fehler aufgetreten? */
if ((b > 0L) && (ret > 0))
{
ret = Fwrite(fd, b, buffer);
if (ret != buf_size)
ret = -ENOSPC;
}
if (ret < 0)
antw = (short)ret;
else
antw = 0;
}
else
antw = 1;
Fclose(fd);
if (antw == -ENOSPC)
Fdelete(name);
if (buffer != static_buffer)
Mfree(buffer);
if (verbose)
end_aktion();
}
else
antw = fd;
Last_mouse();
return antw;
}
GLOBAL WORD save(TEXTP t_ptr)
{
WORD antw;
if (file_exist(t_ptr->filename))
{
if (file_readonly(t_ptr->filename))
{
FILENAME file;
t_ptr->readonly = TRUE;
file_name(t_ptr->filename, file, FALSE);
snote(1, READONLY, file);
return -39;
}
else
t_ptr->readonly = FALSE;
if (t_ptr->file_date_time != -1L)
{
LONG date_time = file_time(t_ptr->filename, NULL, NULL);
if (date_time != t_ptr->file_date_time)
{
FILENAME name;
file_name(t_ptr->filename, name, FALSE);
if (snote(1, MOVED2, name) == 2)
return -1;
}
}
}
back_up(t_ptr);
antw = save_datei(t_ptr->filename, &t_ptr->text, TRUE, t_ptr->ending);
if (antw == 0)
{
t_ptr->moved = 0;
t_ptr->file_date_time = file_time(t_ptr->filename, NULL, NULL);
t_ptr->count = local_time->tm_min;
/* OLGA informieren */
do_OLGA(OLGA_UPDATE, t_ptr->filename, NULL);
}
else
{
if (antw == -ENOSPC)
{
UBYTE tmp[20];
make_shortpath(t_ptr->filename, tmp, 19);
snote(1, NOSPACE, tmp);
}
else
note(1, WRITEERR);
/* restore_back_up(t_ptr); */
t_ptr->file_date_time = -1L;
}
return antw;
}
GLOBAL WORD save_as(TEXTP t_ptr, UBYTE *name)
{
WORD antw;
if (file_exist(name))
{
if (file_readonly(name))
{
FILENAME file;
file_name(t_ptr->filename, file, FALSE);
snote(1,READONLY, file);
return -39;
}
}
antw = save_datei(name, &t_ptr->text, TRUE, t_ptr->ending);
if (antw != 0)
{
if (antw == -ENOSPC)
{
UBYTE tmp[20];
make_shortpath(t_ptr->filename, tmp, 19);
snote(1, NOSPACE, tmp);
}
else
note(1, WRITEERR);
/* restore_back_up(t_ptr);*/
}
return(antw);
}
GLOBAL BOOLEAN save_new(UBYTE *name, FSEL *fsel, UBYTE *text)
{
fsel->name[0] = EOS;
if (!select_file(fsel,name, text))
return FALSE;
if (file_exist(name))
{
if (note(1,EXIST)==2) return
FALSE;
}
return TRUE;
}